package com.zjj.concurrent.feature.visibility;

/**
 * @author zhanglei.zjj
 * @description 并发编程可见性问题分析
 * 生成汇编指令的jvm参数如下，需要hsdis-amd64.dll放在jre中
 * -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -Xcomp
 * @date 2023/5/13 11:54
 */
public class VisibilityTest {
    private /*volatile*/ boolean flag = true;
    private Integer count = 0;
    public void refresh() {
        flag = false;
        System.out.println(Thread.currentThread().getName() + "修改flag");
    }

    public void load() {
        System.out.println(Thread.currentThread().getName() + "开始执行.....");
        int i = 0;
        while (flag) {
            i++;
            //TODO  业务逻辑
            /*
                解决可见性
             */
            // yield释放cpu时间片
//            Thread.yield();

            // flag 加volatile

            // 内存屏障
//            UnsafeFactory.getUnsafe().storeFence();

            // synchronized
            System.out.println("123456");

            // LockSupport.unpark
//            LockSupport.unpark(Thread.currentThread());

            // Sleep
//            try {
//                Thread.sleep(200);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }

            // Integer内部使用了final
//            count++;
        }
        System.out.println(Thread.currentThread().getName() + "跳出循环: i=" + i);
    }

    public static void main(String[] args) throws InterruptedException {
        VisibilityTest test = new VisibilityTest();

        // 线程threadA模拟数据加载场景
        Thread threadA = new Thread(() -> test.load(), "threadA");
        threadA.start();

        // 让threadA执行一会儿
        Thread.sleep(1000);
        // 线程threadB通过flag控制threadA的执行时间
        Thread threadB = new Thread(() -> test.refresh(), "threadB");
        threadB.start();

    }


    public static void shortWait(long interval) {
        long start = System.nanoTime();
        long end;
        do {
            end = System.nanoTime();
        } while (start + interval >= end);
    }
}
